Skip to content

LinkML guardrails: GENERATED banners, regen-no-diff CI, schema-adherence test#13

Merged
IanMayo merged 1 commit into
mainfrom
claude/linkml-guardrails
Jun 14, 2026
Merged

LinkML guardrails: GENERATED banners, regen-no-diff CI, schema-adherence test#13
IanMayo merged 1 commit into
mainfrom
claude/linkml-guardrails

Conversation

@IanMayo

@IanMayo IanMayo commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

Makes Principle I (LinkML is the one source of truth, DEC-57) enforceable rather than aspirational — the three deferred guardrails logged in ADR-0011/0012. (The fourth note — migrating the app's inline shapes onto the generated TS — stays its own spec.)

The three guardrails

# Guardrail What it does
1 GENERATED banners schema/generate.sh stamps @generated — DO NOT EDIT on every derived file (a // block on remit.ts, a $comment first-key on remit.schema.json — textual insert, no reformat churn — and an HTML comment on index.html), plus .gitattributes marking them linguist-generated.
2 regen-no-diff CI (schema-regen.yml) Regenerates from the schema and fails on any diff under schema/gen/ + site/data-model/, so the committed artefacts can't silently fall out of step with schema/*.yaml. Toolchain pinned (linkml/linkml-runtime==1.11.1, Python 3.11) and verified byte-reproducible (idempotent, empty diff).
3 schema-adherence test (test/schema-adherence.test.mjs) Builds real instances — a committed Orbat (red/green/own-force) and a kernel Plan (Stamp/Scores/Materialisation) — and validates them against the generated JSON Schema with ajv (draft-2019-09).

The adherence guard earned its keep immediately

Validating real instances surfaced that the documented Waypoint square-vs-hex drift (bugs.md) is broader than SteeringDelta — it also hits Asset.position, Stamp.start, Materialisation.trajectory — and flagged two more: the kernel carries appetites as a {axis:setting} map where the schema models Appetite[], and TideDecision shapes differently.

These pre-existing drifts are stripped per class (the test's DRIFT map) before strict validation, so the guard is green yet still fails on any new drift (proven by an undeclared-field assertion). Each is recorded in bugs.md; the Waypoint→HexCell migration + appetites/tide reconciliation (then emptying DRIFT) is the concrete next follow-up this guard makes visible — deliberately not done here to keep this a pure guardrail, not a schema migration.

Notes for review

  • Bonus gap closed: the unit suite (test:unit — golden fixtures, ORBAT, routing) had never run in CI; only e2e + typecheck did. Added unit.yml so the adherence guard (and all the others) actually fire on PRs.
  • Dependency (ADR-0014): ajv added dev-only — test-only, never imported by app/ or the kernel. No runtime dependency.
  • Scope: tooling / CI / test only. The sole change to generated output is the banner text; no app/ or kernel code changed.
  • Green locally: 32 unit tests (+2), 0 typecheck errors.
  • New CI checks on this PR: schema-regen and unit (first run).

Recorded as ADR-0029; drifts in bugs.md; key_facts.md + work-log updated.

https://claude.ai/code/session_01EhtBoKXg6bHnKdquacyknf


Generated by Claude Code

…, adherence test

Makes Principle I (LinkML = source of truth, DEC-57) enforceable rather than
aspirational — the three deferred ADR-0011/0012 follow-ups:

- GENERATED banners on every derived artefact (generate.sh stamps remit.ts /
  remit.schema.json / index.html) + .gitattributes linguist-generated.
- regen-no-diff CI (schema-regen.yml): regenerates from the schema and fails on
  any schema/gen + site/data-model drift; toolchain pinned (linkml /
  linkml-runtime==1.11.1, Python 3.11), byte-reproducible.
- schema-adherence test (test/schema-adherence.test.mjs, ajv dev-only): validates
  a committed Orbat + a kernel Plan against the generated JSON Schema; wired into
  a new unit.yml CI job (the unit suite never ran in CI before — only e2e +
  typecheck did).

The adherence guard immediately surfaced the full extent of the documented
Waypoint hex/square drift (Asset.position, Stamp.start, Materialisation.trajectory)
plus appetites map-vs-list and TideDecision (bugs.md) — stripped and tracked via
the test's DRIFT map; the Waypoint->HexCell migration is the surfaced follow-up.

ajv added as a dev-only dependency (ADR-0014-approved, test-only — never imported
by app/ or the kernel). 32 unit tests (+2) green; 0 typecheck errors. ADR-0029.

https://claude.ai/code/session_01EhtBoKXg6bHnKdquacyknf
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-14 10:53 UTC

@IanMayo IanMayo merged commit 660aa4e into main Jun 14, 2026
5 checks passed
@IanMayo IanMayo deleted the claude/linkml-guardrails branch June 14, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants